﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using IS.Base;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.InteropServices;
using SendReceive;
using GoogleMaps;
namespace receiveSRV
{
    
    public class sendReceive
    {
        static Socket a = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        static int port = 456;
        static string IP = "";
        public static Thread srv;
        private static int debugMode = 2;//0, 1, 2, 3
        static private string IPinfo = "";
        public static List<reportlog.CLIENT_REPORTLOG_OBJ> listnew = new List<reportlog.CLIENT_REPORTLOG_OBJ>();
        public static List<reportlog.CLIENT_REPORTLOG_OBJ> listpre = new List<reportlog.CLIENT_REPORTLOG_OBJ>();
        public static bool writeit(StreamWriter w, string content)
        {
            try
            {
                if (w != null)
                {
                    w.WriteLine("{0} - {1}", DateTime.Now.ToString("yyyyMMdd HH:mm:ss"), content);
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public static bool debug(string logfile, string content)//default 1
        {
            return debug(1, logfile, content);
        }
        public static bool debug(int level, string logfile, string content)//default 1
        {
            if (debugMode < level)
            {
                return false;//abort writing 
            }
            try
            {
                StreamWriter w = File.AppendText(logfile);
                writeit(w, content);
                w.Close();
                w.Dispose();
            }
            catch (Exception ex)
            {
                return false;
            }
            return false;
        }

        public static void insertlistpre(reportlog.CLIENT_REPORTLOG_OBJ b, List<reportlog.CLIENT_REPORTLOG_OBJ> lspre)
        {
            
            b.REPORTTIMEPRE = b.REPORTTIME;
            b.LATITUDEPRE = b.LATITUDE;
            b.LONGITUDEPRE = b.LONGITUDE;
            b.OPENAIRPRE = b.OPENAIR;
            b.OPENDOORPRE = b.OPENDOOR;
            b.ENGINEONPRE = b.ENGINEON;
            b.OPENENGINEPRE = b.OPENENGINE;
            b.MECHANICSPEEDPRE = b.MECHANICSPEED;
            b.GPSSPEEDPRE = b.GPSSPEED;
            lspre.Add(b);
            debug(2, "listpre.txt", string.Format("Ghi thành công: DEVICEID({0}) LAT({1}) LONG({2}) TIME({3})", b.DEVICEID.ToString(), b.LATITUDE, b.LONGITUDE, b.REPORTTIME.ToString("yyyyMMdd HH:mm:ss")));
       
        }
        public static void updatelistpre(reportlog.CLIENT_REPORTLOG_OBJ b, List<reportlog.CLIENT_REPORTLOG_OBJ> lspre)
        {
           int j= 0;
           for (int i = 0; i < lspre.Count - 1; i++)
           {
              if (b.DEVICEID == lspre[i].DEVICEID)
                     j=i;
                     break;
           }
           b.REPORTTIMEPRE = lspre[j].REPORTTIME;
           b.LATITUDEPRE = lspre[j].LATITUDE;
           b.LONGITUDEPRE = lspre[j].LONGITUDE;
           b.OPENAIRPRE = lspre[j].OPENAIR;
           b.OPENDOORPRE = lspre[j].OPENDOOR;
           b.ENGINEONPRE = lspre[j].ENGINEON;
           b.OPENENGINEPRE = lspre[j].OPENENGINE;
           b.MECHANICSPEEDPRE = lspre[j].MECHANICSPEED;
           b.GPSSPEEDPRE = lspre[j].GPSSPEED;
           lspre.RemoveAt(j);
           lspre.Add(b);
           debug(2, "listpre.txt", string.Format("Update thành công: DEVICEID({0}) LAT({1}) LONG({2}) TIME({3})", b.DEVICEID.ToString(), b.LATITUDE, b.LONGITUDE, b.REPORTTIME.ToString("yyyyMMdd HH:mm:ss")));
        }

      
        public static void insertlistnew(reportlog.CLIENT_REPORTLOG_OBJ b, List<reportlog.CLIENT_REPORTLOG_OBJ> lsnew, List<reportlog.CLIENT_REPORTLOG_OBJ> lspre)
        {
                int j = 0;
                for (int i = 0; i < lspre.Count - 1; i++)
                {
                    if (b.DEVICEID == lspre[i].DEVICEID)
                        j = i;
                    break;
                }
                b.REPORTTIMEPRE = lspre[j].REPORTTIME;
                b.LATITUDEPRE = lspre[j].LATITUDE;
                b.LONGITUDEPRE = lspre[j].LONGITUDE;
                b.OPENAIRPRE = lspre[j].OPENAIR;
                b.OPENDOORPRE = lspre[j].OPENDOOR;
                b.ENGINEONPRE = lspre[j].ENGINEON;
                b.OPENENGINEPRE = lspre[j].OPENENGINE;
                b.MECHANICSPEEDPRE = lspre[j].MECHANICSPEED;
                b.GPSSPEEDPRE = lspre[j].GPSSPEED;
                lsnew.Add(b);
                debug(2, "listnew.txt", string.Format("Ghi thành công: DEVICEID({0}) LAT({1}) LONG({2}) TIME({3})", b.DEVICEID.ToString(), b.LATITUDE, b.LONGITUDE, b.REPORTTIME.ToString("yyyyMMdd HH:mm:ss")));
        }
        public static bool Threadputdata()
        {
            Thread senddata = new Thread(new ThreadStart(putdata)) { Name = "Put Data Thread" };
            if (senddata.IsAlive)
            {
                return false;
            }
            try
            {
                if (temp == false)
                {
                    senddata.Start();
                }
                return true;
            }
            catch
            {
                return false;
            } 
        }
        static bool temp = false;
        public static void putdata()
        {
            temp = true;
            for (int i = 0; i < listnew.Count; i++)
            {
                var item = listnew[i];
                writeData(item);
                debug(2, "listdelete.txt", string.Format("Ghi thành công: DEVICEID({0}) LAT({1}) LONG({2}) TIME({3})", item.DEVICEID.ToString(), item.LATITUDE, item.LONGITUDE, item.REPORTTIME.ToString("yyyyMMdd HH:mm:ss")));
                if (item != null)
                {
                    listnew.Remove(item);                    
                }
            }
            temp = false;
        }
        public static void writeData(reportlog.CLIENT_REPORTLOG_OBJ b)
        {
            int ret = 0;
            try
            {
                reportlog.ServiceTC3Client clients= new reportlog.ServiceTC3Client();
                ret = clients.insert(b);
                if (ret == 0)
                {
                    debug(2,"database.log", string.Format("Ghi thành công: DEVICEID({0}) LAT({1}) LONG({2}) TIME({3})", b.DEVICEID.ToString(), b.LATITUDE, b.LONGITUDE, b.REPORTTIME.ToString("yyyyMMdd HH:mm:ss")));
                }
                else
                {
                    debug(1, "database.log", string.Format("Lỗi ghi DEVICEID({0}) LAT({1}) LONG({2}) TIME({3})", b.DEVICEID.ToString(), b.LATITUDE, b.LONGITUDE, b.REPORTTIME.ToString("yyyyMMdd HH:mm:ss")));
                }
                clients.Close();
            }
            catch (Exception ex)
            {
                debug(1,"transaction.txt", string.Format("writeData- Error writing data MES({0})  SOURCE({1})" , ex.Message, ex.Source));
            }
            return;

        }
        public static DateTime convertDate(int year, int month, int day, int hour, int min, int sec)
        {
            DateTime d;
            if (year < 2000)
                year += 2000;
            try
            {
                d = new DateTime(year, month, day, hour, min, sec);
            }
            catch (Exception ex)
            {
                d = new DateTime(1753, 1, 1, 0, 0, 0);
            }
            return d;
        }
        public static bool checklistpre(List<reportlog.CLIENT_REPORTLOG_OBJ> lspre, reportlog.CLIENT_REPORTLOG_OBJ b)
        {
            bool kt = true;
            for (int i = 0; i < listpre.Count - 1; i++)
            {
                if (b.DEVICEID != lspre[i].DEVICEID)
                    kt = true;
                else
                    kt = false;
            }
            return kt;
        }
        public static void saveMe(object p)
        {
            try
            {
                packet a = (packet)p;
                reportlog.CLIENT_REPORTLOG_OBJ b = new reportlog.CLIENT_REPORTLOG_OBJ();

                b.CODE = "";
                b.CODEVIEW = "";
                b.COMPANYCODE = "3TCCOM";// revising
                b.NAME = "";
                b.NOTE = "";
                b.LOCK = 0;
                b.LOCKDATE = DateTime.Now;
                b.EDITUSER = "";
                b.EDITTIME = DateTime.Now;
                //b.EDITTIME = DateTime.Now;
                //report data

                b.DEVICEID = (int)(convert.rol32(a.DeviceID));
                b.DRIVERID = (int)(convert.rol32(a.DriverID));
                b.REPORTTIME = convertDate(a._year, a._month, a._day, a._hour, a._min, a._sec);
                b.LATITUDE = convert.byte2Lat(a.Latitude0, a.Latitude1, a.Latitude2, a.Latitude3); //a.Latitude;
                b.LONGITUDE = convert.byte2Lat(a.Longitude0, a.Longitude1, a.Longitude2, a.Longitude3);//a.Longitude;
                b.GPSSPEED = a.GPSSpeed;
                //digital signal
                b.FUELLEVEL = convert.rol16(a.Fuellevel);
                b.MECHANICSPEED = a.Mechanicspeed;
                b.MECHANICDISTANCE = convert.rol32(a.Mechanicdistance);
                b.DATADELETE = convert.rol16(a.deleteDataCount);
                b.WASTEDISTANCE = convert.rol16(a.UnhiredDistanc);
                b.PICKUPTIME = convertDate(a._hiredYear, a._hiredMonth, a._hiredDay, a._hiredHour, a._hiredMin, 0);
                b.FARE = a.hiredMoney0 * 256 * 256 + a.hiredMoney1 * 256 + a.hiredMoney2;
                b.WAITINGTIME = convert.rol16(a.waiting);
                b.ENDFARE = convertDate(a._unhiredYear, a._unhiredMonth, a._unhiredDay, a._unhiredHour, a._unhiredMin, 0); ;
                b.FAREDISTANCE = a.hiredDistance0 * 256 * 256 + a.hiredDistance1 * 256 + a.hiredDistance2;
                //
                //a.DigitalSignal;
                //byte 1
                b.POSITIONFIX = (int)(a.DigitalSignal & 128) >> 7;
                b.SOS = (int)(a.DigitalSignal & 64) >> 6;
                b.OPENENGINE = (int)(a.DigitalSignal  & 32) >> 5;
                b.OPENDOOR = (int)(a.DigitalSignal & 16) >> 4;
                b.OPENAIR = (int)(a.DigitalSignal & 8) >> 3;
                b.FUELRELAY = (int)(a.DigitalSignal & 4) >> 2;
                b.CAMERARELAY = (int)(a.DigitalSignal & 2) >> 1;
                b.INCAR = (int)(a.DigitalSignal & 1);
                //byte 2
                b.INFARE = (int)(a.DigitalSignal & 32768) >> 15;
                b.INFARECAMERE = (int)(a.DigitalSignal  & 16384) >> 14;
                b.ENGINEON = (int)(a.DigitalSignal & 8192) >> 13;
                b.CHECKER = (int)(a.DigitalSignal & 4096) >> 12;
                b.WAITINGFARE = (int)(a.DigitalSignal & 2048) >> 11;
                b.ENDFAREEVENT = (int)(a.DigitalSignal & 1024) >> 10;
                b.MEMORY = (int)(a.DigitalSignal & 512) >> 9;
                b.REPLAY = (int)(a.DigitalSignal & 256) >> 8;

                int isinsertlist = 0;
                bool kt;
                if (!checklistpre(listpre, b))//look up report has ID same report in the listpre: find
                {
                    isinsertlist = 1;
                }
                if (isinsertlist == 0)
                {
                    insertlistpre(b, listpre);
                    insertlistnew(b, listnew, listpre);     
                }
                else
                {
                    updatelistpre(b, listpre);
                    insertlistnew(b, listnew, listpre);                  
                }
                kt = Threadputdata();
               // putdata();
                debug(2,"transaction.txt", "saveMe61- object created, written");

            }
            catch (Exception ex)
            {
                debug(1,"transaction.txt", string.Format("saveMe61- object creating error MES({0}) SOURCE({1})", ex.Message,ex.Source));
                return;
            }
        }
        public static void saveMeS(object p)
        {
            try
            {
                packetS a = (packetS)p;
                reportlog.CLIENT_REPORTLOG_OBJ b = new reportlog.CLIENT_REPORTLOG_OBJ();
                // for management data
                b.CODE = "";
                b.CODEVIEW = "";
                b.COMPANYCODE = "3TCCOM";//revising
                b.NAME = "";
                b.NOTE = "";
                b.LOCK = 0;
                b.LOCKDATE = DateTime.Now;
                b.EDITUSER = "";
                b.EDITTIME = DateTime.Now;
                //report data

                b.DEVICEID = (int)(convert.rol32(a.DeviceID));
                debug(3,"transaction.txt", "saveMe56- Assign object 1");
                b.DRIVERID = (int)(convert.rol32(a.DriverID));
                debug(3, "transaction.txt", "saveMe56- Assign object 2:" + a._year.ToString() + ":" + a._month.ToString() + ":" + a._day.ToString() + ":" + a._hour.ToString() + ":" + a._min.ToString() + ":" + a._sec.ToString());
                b.REPORTTIME = convertDate(a._year, a._month, a._day, a._hour, a._min, a._sec);
                //14:10:13:26:2:17
                debug(3, "transaction.txt", "saveMe56- Assign object 3A");
                b.LATITUDE = convert.byte2Lat(a.Latitude0, a.Latitude1, a.Latitude2, a.Latitude3); //a.Latitude;
                debug(3, "transaction.txt", "saveMe56- Assign object 3");
                b.LONGITUDE = convert.byte2Lat(a.Longitude0, a.Longitude1, a.Longitude2, a.Longitude3);//a.Longitude;
                debug(3, "transaction.txt", "saveMe56- Assign object 4");
                b.GPSSPEED = a.GPSSpeed;
                debug(3, "transaction.txt", "saveMe56- Assign object 5");
                //digital signal
                b.FUELLEVEL = convert.rol16(a.Fuellevel);
                debug(3, "transaction.txt", "saveMe56- Assign object 6");
                b.MECHANICSPEED = a.Mechanicspeed;
                debug(3, "transaction.txt", "saveMe56- Assign object 7");
                b.MECHANICDISTANCE = convert.rol32(a.Mechanicdistance);
                debug(3, "transaction.txt", "saveMe56- Assign object 8");
                b.DATADELETE = convert.rol16(a.deleteDataCount);
                debug(3, "transaction.txt", "saveMe56- Assign object 9");
                b.WASTEDISTANCE = convert.rol16(a.UnhiredDistanc);
                debug(3, "transaction.txt", "saveMe56- Assign object 10");
                b.PICKUPTIME = convertDate(a._hiredYear, a._hiredMonth, a._hiredDay, a._hiredHour, a._hiredMin, 0);
                debug(3, "transaction.txt", "saveMe56- Assign object 11");
                b.FARE = a.hiredMoney0 * 256 * 256 + a.hiredMoney1 * 256 + a.hiredMoney2;
                debug(3, "transaction.txt", "saveMe56- Assign object 12");
                b.WAITINGTIME = convert.rol16(a.waiting);
                debug(3, "transaction.txt", "saveMe56- Assign object 13");
                b.ENDFARE = DateTime.Now;
                b.FAREDISTANCE = a.hiredDistance0 * 256 * 256 + a.hiredDistance1 * 256 + a.hiredDistance2;
                debug(3,"transaction.txt", "saveMe56- Assign object 14");
                //
                //a.DigitalSignal;
                //byte 1
                b.POSITIONFIX = (int)(a.DigitalSignal & 128) >> 7;
                b.SOS = (int)(a.DigitalSignal & 64) >> 6;
                b.OPENENGINE = (int)(a.DigitalSignal & 32) >> 5;
                b.OPENDOOR = (int)(a.DigitalSignal & 16) >> 4;
                b.OPENAIR = (int)(a.DigitalSignal & 8) >> 3;
                b.FUELRELAY = (int)(a.DigitalSignal & 4) >> 2;
                b.CAMERARELAY = (int)(a.DigitalSignal & 2) >> 1;
                b.INCAR = (int)(a.DigitalSignal & 1);
                //byte 2
                b.INFARE = (int)(a.DigitalSignal & 32768) >> 15;
                b.INFARECAMERE = (int)(a.DigitalSignal & 16384) >> 14;
                b.ENGINEON = (int)(a.DigitalSignal & 8192) >> 13;
                b.CHECKER = (int)(a.DigitalSignal & 4096) >> 12;
                b.WAITINGFARE = (int)(a.DigitalSignal & 2048) >> 11;
                b.ENDFAREEVENT = (int)(a.DigitalSignal & 1024) >> 10;
                b.MEMORY = (int)(a.DigitalSignal & 512) >> 9;
                b.REPLAY = (int)(a.DigitalSignal & 256) >> 8;
                

                int isinsertlist = 0;
                bool kt;
                if (!checklistpre(listpre, b))//look up report has ID same report in the listpre:  find
                {
                    isinsertlist = 1;
                }
                if (isinsertlist == 0)
                {
                    insertlistpre(b, listpre);
                    insertlistnew(b, listnew, listpre);
                }
                else
                {
                    insertlistnew(b, listnew, listpre);
                    updatelistpre(b, listpre);
                }
                kt = Threadputdata();
              //  putdata();
                debug(2,"transaction.txt", "saveMe56- object created, written ");
            }
            catch (Exception ex)
            {
                debug(1,"transaction.txt", string.Format("saveMe56- object creating error MES({0}) SOURCE({1})", ex.Message, ex.Source));
            }
        }
        public static void saveMeSS(object p)
        {
            try
            {
                debug(3,"transaction.txt", "saveMe43- Begin saving data ");
                packetSS a = (packetSS)p;
                debug(3, "transaction.txt", "saveMe43- Assign object ");
                reportlog.CLIENT_REPORTLOG_OBJ b = new reportlog.CLIENT_REPORTLOG_OBJ();
                // for management data
                b.CODE = "";
                b.CODEVIEW = "";
                b.COMPANYCODE = "3TCCOM";//revising
                b.NAME = "";
                b.NOTE = "";
                b.LOCK = 0;
                b.LOCKDATE = DateTime.Now;
                b.EDITUSER = "";
                b.EDITTIME = DateTime.Now;
                //report data

                b.DEVICEID = (int)convert.rol32(a.DeviceID);
                debug(3, "transaction.txt", "saveMe43- Assign object 1");
                b.DRIVERID = (int)convert.rol32(a.DriverID);
                debug(3, "transaction.txt", "saveMe43- Assign object 2:" + a._year.ToString() + ":" + a._month.ToString() + ":" + a._day.ToString() + ":" + a._hour.ToString() + ":" + a._min.ToString() + ":" + a._sec.ToString());
                b.REPORTTIME = convertDate(a._year, a._month, a._day, a._hour, a._min, a._sec);
                //14:10:13:26:2:17
                debug(3, "transaction.txt", "saveMe43- Assign object 3A");
                b.LATITUDE = convert.byte2Lat(a.Latitude0, a.Latitude1, a.Latitude2, a.Latitude3); //a.Latitude;
                debug(3, "transaction.txt", "saveMe43- Assign object 3");
                b.LONGITUDE = convert.byte2Lat(a.Longitude0, a.Longitude1, a.Longitude2, a.Longitude3);//a.Longitude;
                debug(3, "transaction.txt", "saveMe43- Assign object 4");
                b.GPSSPEED = a.GPSSpeed;
                debug(3, "transaction.txt", "saveMe43- Assign object 5");
                //digital signal
                b.FUELLEVEL = convert.rol16(a.Fuellevel);
                debug(3, "transaction.txt", "saveMe43- Assign object 6");
                b.MECHANICSPEED = a.Mechanicspeed;
                debug(3, "transaction.txt", "saveMe43- Assign object 7");
                b.MECHANICDISTANCE = convert.rol32(a.Mechanicdistance);
                debug(3, "transaction.txt", "saveMe43- Assign object 8");
                b.DATADELETE = convert.rol16(a.deleteDataCount);
                debug(3, "transaction.txt", "saveMe43- Assign object 9");
                b.WASTEDISTANCE = convert.rol16(a.UnhiredDistanc);
                debug(3, "transaction.txt", "saveMe43- Assign object 10");

                b.PICKUPTIME = DateTime.Now; ;// new DateTime(a._hiredYear, a._hiredMonth, a._hiredDay, a._hiredHour, a._hiredMin, 0);
                debug(3, "transaction.txt", "saveMe43- Assign object 11");
                b.FARE = 0;// a.hiredMoney0 * 256 * 256 + a.hiredMoney1 * 256 + a.hiredMoney2;
                debug(3, "transaction.txt", "saveMe43- Assign object 12");
                b.WAITINGTIME = 0;// a.waiting;
                debug(3, "transaction.txt", "saveMe43- Assign object 13");
                b.ENDFARE = DateTime.Now;
                b.FAREDISTANCE = 0;// a.hiredDistance0 * 256 * 256 + a.hiredDistance1 * 256 + a.hiredDistance2;
                debug(3, "transaction.txt", "saveMe43- Assign object 14");
                //
                //a.DigitalSignal;
                //byte 1
                b.POSITIONFIX = (int)(a.DigitalSignal & 128) >> 7;
                b.SOS = (int)(a.DigitalSignal & 64) >> 6;
                b.OPENENGINE = (int)(a.DigitalSignal & 32) >> 5;
                b.OPENDOOR = (int)(a.DigitalSignal & 16) >> 4;
                b.OPENAIR = (int)(a.DigitalSignal & 8) >> 3;
                b.FUELRELAY = (int)(a.DigitalSignal & 4) >> 2;
                b.CAMERARELAY = (int)(a.DigitalSignal & 2) >> 1;
                b.INCAR = (int)(a.DigitalSignal & 1);
                //byte 2
                b.INFARE = (int)(a.DigitalSignal & 32768) >> 15;
                b.INFARECAMERE = (int)(a.DigitalSignal & 16384) >> 14;
                b.ENGINEON = (int)(a.DigitalSignal & 8192) >> 13;
                b.CHECKER = (int)(a.DigitalSignal & 4096) >> 12;
                b.WAITINGFARE = (int)(a.DigitalSignal & 2048) >> 11;
                b.ENDFAREEVENT = (int)(a.DigitalSignal & 1024) >> 10;
                b.MEMORY = (int)(a.DigitalSignal & 512) >> 9;
                b.REPLAY = (int)(a.DigitalSignal & 256) >> 8;
                

                int isinsertlist = 0;
                bool kt;
                if (!checklistpre(listpre, b))//look up report has ID same report in the listpre: find
                {
                    isinsertlist = 1;
                }
                if (isinsertlist == 0)
                {
                    insertlistpre(b, listpre);
                    insertlistnew(b, listnew, listpre);
                }
                else
                {
                    insertlistnew(b, listnew, listpre);
                    updatelistpre(b, listpre);
                }
                kt = Threadputdata();
                //putdata();
                debug(2, "transaction.txt", "saveMe43- object created, written ");
            }
            catch (Exception ex)
            {
                debug(1, "transaction.txt", string.Format("saveMe43- object creating error MES({0}) SOURCE({1})", ex.Message, ex.Source));

            }
        }
        //public static bool buildConnectionstring(string databasesever, string database, string username, string password)
        //{
        //    connectionstring = "Data Source=" + databasesever + ";Initial Catalog=" + database + ";User ID=" + username + ";Password=" + password + "";
        //    return true;
        //}
        //public static bool insertInfomation(byte[] data)
        //{
        //    string sql;

        //    return true;
        //}
        public static bool checkConnect(string ip, int port)
        {
            sendCommand scm = new sendCommand(ip, port);
            if (scm.connect())
            {
                scm.disconnect();
                scm = null;
                return true;
            }
            return false;
        }
        public static bool checkSevice(string ip, int port)
        {
            debug(1,"logconnect.txt", "Try to connect");
            if (sendReceive.startListen(ip, port))
            {
                sendReceive.stopListen();
                debug(1, "logconnect.txt", "Try to connect false " + ip + ":" + port.ToString());
                return true;
            }
            debug(1, "logconnect.txt", "Try to OK");
            return false;

        }

        public static bool startListen()
        {
            srv = new Thread(new ThreadStart(hello));
            if (srv.IsAlive)
            {
                return false;
            }
            try
            {
                srv.Start();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public static bool startListen(string ip, int iport)
        {
            IP = ip;
            port = iport;
            srv = new Thread(new ThreadStart(hello));
            if (srv.IsAlive)
            {
                return false;
            }
            try
            {
                srv.Start();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public static bool stopListen()
        {
            if (srv != null)
            {
                if (!srv.IsAlive)
                {
                    return false;
                }
            }
            else
            {
                return true;
            }
            if (a.Connected)
            {
                a.Disconnect(false);
            }
            a.Dispose();
            srv.Abort();
            srv = null;
            return true;
        }
        public static void hello()
        {
            a = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress current = null;
            IPAddress.TryParse(IP, out current);
            debug(1, "logconnect.txt", "connection IP: " + IP.ToString());

            IPEndPoint ep = new IPEndPoint(current, port);
            debug(1, "logconnect.txt", "Create end point: " + ep.ToString());
            try
            {
                a.Bind(ep);
            }
            catch (Exception ex)
            {
                debug(1, "logconnect.txt", "Error binding end point to socket: " + ex.Message + ":" + ex.Source);
            }
            debug(1, "logconnect.txt", "Binding end point to socket ok");
            try
            {
                a.Listen(1000);
            }
            catch (Exception ex)
            {
                debug(1, "logconnect.txt", "Error listen: " + ex.Message + ":" + ex.Source);
            }
            debug(1, "logconnect.txt", "Socket listen 10");
            while (true)
            {
                allDone.Reset();
               debug(3, "logconnect.txt", "ManualResetEvent Reset");
                try
                {
                    IAsyncResult abc = a.BeginAccept(new AsyncCallback(OnClientConnect), a);
                                       debug(3, "logconnect.txt", "Begin Accept"); 
                }
                catch (Exception ex)
                {
                    debug(1, "logconnect.txt", "Error BeginAccept" + ex.Message + ":" + ex.Source.ToString() + ":" + ex.Data.ToString());
                }
                allDone.WaitOne();
                               debug(3, "logconnect.txt", "WaitOne done");
            }
        }
        static public void OnClientConnect(IAsyncResult ar)
        {
            try
            {
                debug(3, "transaction.txt", "Begin transaction");
                allDone.Set();

                // Get the socket that handles the client request.
                Socket listener = (Socket)ar.AsyncState;
                debug(3,"transaction.txt", "Socket assigned");
                Socket handler = listener.EndAccept(ar);
                if (checkSource(handler, out IPinfo))
                {
                    debug(2, "transaction.txt", string.Format("Socket End Accept IP({0})", IPinfo));
                }

                // Create the state object.
                StateObject state = new StateObject();
                state.workSocket = handler;
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
                if (checkSource(handler, out IPinfo))
                {
                    debug(2, "transaction.txt", string.Format("Socket Beginreceive new ({0})",IPinfo));
                }
            }
            catch (Exception ex)
            {
                debug(1, "transaction.txt", string.Format("OnClientConnect - Error MES({0}) SOURCE({1})", ex.Message,ex.Source));
            }

        }
        public static bool checkSource(Socket handler, out string IP)
        {
            IP = "";
            try
            {
                if (handler == null)
                {
                    return true;
                }
                if (handler.RemoteEndPoint == null)
                {
                    return true;
                }
                if (handler.LocalEndPoint == null)
                {
                    return true;
                }
                if (((IPEndPoint)handler.RemoteEndPoint).Address.Equals(((IPEndPoint)handler.LocalEndPoint).Address))
                {
                    return false;
                }
                IP = handler.RemoteEndPoint.ToString();
                return true;
            }
            catch (Exception ex)
            {
                IP = ex.Message;
                return true;
            }
        }
        public static unsafe bool checkPack(packet p)
        {
            try{
            if (p.header0 == '3' && p.header1 == 'T' && p.header2 == 'C'
                                    && p.endPack0 == '*' && p.endPack1 == 13 && p.endPack2 == 10
                                    && p.Packetcode == 0x55)
            {
                return true;
            }
            return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public static unsafe bool checkPack(packetS p)
        {
            try
            {
                if (p.header0 == '3' && p.header1 == 'T' && p.header2 == 'C'
                                        && p.endPack0 == '*' && p.endPack1 == 13 && p.endPack2 == 10
                                        && p.Packetcode == 0x55)
                {
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        public static unsafe bool checkPack(packetSS p)
        {
            try{
            if (p.header0 == '3' && p.header1 == 'T' && p.header2 == 'C'
                                    && p.endPack0 == '*' && p.endPack1 == 13 && p.endPack2 == 10
                                    && p.Packetcode == 0x55)
            {
                return true;
            }
            return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        
        public static unsafe void ReadCallback(IAsyncResult ar)
        {

            String content = String.Empty;
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            debug(3,"transaction.txt", "Readcallback-ReadCallback 1");
            StateObject state = (StateObject)ar.AsyncState;
//            debug(2, "transaction.txt", "Readcallback-ReadCallback 2");
            if (state == null)
            {
                debug(2, "transaction.txt", "Readcallback-Null state");
                return ;
            }
//            debug(2, "transaction.txt", "Readcallback-ReadCallback 3");
            Socket handler = state.workSocket;
//            debug(2, "transaction.txt", "Readcallback-ReadCallback 4");
            if (handler == null)
            {
                debug(2, "transaction.txt", "Readcallback-Null handler");
                return;
            }
            if (checkSource(handler, out IPinfo))
            {
                debug(3, "transaction.txt", string.Format("Readcallback IP({0})-Create socket", IPinfo));
            }
            // Read data from the client socket. 
//            debug(2, "transaction.txt", "Readcallback-ReadCallback 5");
            int bytesRead = 0;
            try
            {
                bytesRead = handler.EndReceive(ar);
            }
            catch (Exception ex)
            {
                debug(2, "transaction.txt", string.Format("Readcallback - READ MES({0})-EndReceive  byte({1})", ex.Message, bytesRead));
            }
//            debug(2, "transaction.txt", "Readcallback-ReadCallback 6");
            if (checkSource(handler, out IPinfo))
            {
                debug(2, "transaction.txt", string.Format("Readcallback IP({0})-EndReceive  byte({1})",IPinfo, bytesRead));
            }
            packet rawp;
            packetS rawps;
            packetSS rawpss;
            //try to process data received from clients
            if (bytesRead > 0)
            {
                if (checkSource(handler, out IPinfo))
                {
                    debug(3, "transaction.txt", string.Format("Readcallback IP ({0})-packet captured ({1})", IPinfo, bytesRead.ToString()));
                }
                int startIndex = 0;
                int endIndex = 0;
                int packLength;
                int lastLenth;
                int countPack = 0;
                //process for each paket
                //locate the first paket 
                try
                {

                    while (startIndex < bytesRead - 3 && !(state.buffer[startIndex] == '3' && state.buffer[startIndex + 1] == 'T' && state.buffer[startIndex + 2] == 'C'))
                    {
                        startIndex++;
                    }
//                    debug(2, "transaction.txt", "ReadCallback - begin second while");
                    //locate until not the end of array
                    IntPtr unmanagedPointer = Marshal.AllocHGlobal(61);//max packet
                    while (startIndex+42 < bytesRead)//43
                    {
                        //try to process
//                        debug(2, "transaction.txt", "ReadCallback - begin second while 1");
                        lastLenth = 61;
                        if (bytesRead - startIndex < lastLenth)
                        {
                            lastLenth = bytesRead - startIndex;//ignore the case that, copy out of range
                        }
//                        debug(2, "transaction.txt", "ReadCallback - begin second while 2");
                        if (lastLenth < 43)
                        {
                            break;//less than a minimum pack 
                        }
                        //debug(2, "transaction.txt", "ReadCallback - begin second while 3");
                        Marshal.Copy(state.buffer, startIndex, unmanagedPointer, lastLenth);
                        packLength = 0;
                        //asign all struct to the packets buffer
                        //debug(2, "transaction.txt", "ReadCallback - begin second while 4");
                        rawp = (packet)Marshal.PtrToStructure(unmanagedPointer, typeof(packet));
                        //debug(2, "transaction.txt", "ReadCallback - begin second while 5");
                        rawps = (packetS)Marshal.PtrToStructure(unmanagedPointer, typeof(packetS));
                        //debug(2, "transaction.txt", "ReadCallback - begin second while 6");
                        rawpss = (packetSS)Marshal.PtrToStructure(unmanagedPointer, typeof(packetSS));
                        //check the leng of data
                        //debug(2, "transaction.txt", "ReadCallback - begin second while 7");
                        bool tryon = checkPack(rawpss);
                        //debug(2, "transaction.txt", "ReadCallback - begin second while 71");
                        if (tryon)
                        {
                            packLength = 43;
                            if (checkSource(handler, out IPinfo))
                            {
                                debug(3, "transaction.txt", string.Format("Readcallback IP({0})-packet processed ({1})", IPinfo, packLength.ToString()));
                            }
                            countPack++;
                            //debug(2, "transaction.txt", "ReadCallback - begin second while 8");
                            Thread t = new Thread(new ParameterizedThreadStart(sendReceive.saveMeSS));
                            //debug(2, "transaction.txt", "ReadCallback - begin second while 9");
                            t.Start(rawpss);
                            //debug(2, "transaction.txt", "ReadCallback - begin second while 10");
                        }
                        else
                            if (lastLenth>=56 &&checkPack(rawps))
                            {
                                //debug(2, "transaction.txt", "ReadCallback - begin second while 111");
                                packLength = 56;
                                if (checkSource(handler, out IPinfo))
                                {

                                    //debug(2, "transaction.txt", "ReadCallback - begin second while 11A");
                                    debug(3, "transaction.txt", string.Format("Readcallback IP({0})- packet processed ({1})", IPinfo, packLength.ToString()));
                                    //debug(2, "transaction.txt", "ReadCallback - begin second while 11B");
                                }
                                //debug(2, "transaction.txt", "ReadCallback - begin second while 112");
                                countPack++;
                                //debug(2, "transaction.txt", "ReadCallback - begin second while 11");
                                Thread t = new Thread(new ParameterizedThreadStart(sendReceive.saveMeS));
                                //debug(2, "transaction.txt", "ReadCallback - begin second while 12");
                                t.Start(rawps);
                                //debug(2, "transaction.txt", "ReadCallback - begin second while 13");
                            }
                            else
                                if (lastLenth >= 56 && checkPack(rawp))
                                {
                                    //debug(2, "transaction.txt", "ReadCallback - begin second while 141");
                                    packLength = 61;
                                    if (checkSource(handler, out IPinfo))
                                    {
                                        debug(3, "transaction.txt", string.Format("Readcallback UP({0})-packet processed ({1})", IPinfo, packLength.ToString()));
                                    }
                                    countPack++;
                                    //debug(2, "transaction.txt", "ReadCallback - begin second while 14");
                                    Thread t = new Thread(new ParameterizedThreadStart(sendReceive.saveMe));
                                    //debug(2, "transaction.txt", "ReadCallback - begin second while 15");
                                    t.Start(rawp);
                                    //debug(2, "transaction.txt", "ReadCallback - begin second while 16");
                                }
                                else
                                {
                                    //locate next point in case error
                                    while (startIndex < bytesRead - 3 && !(state.buffer[startIndex] == '3' && state.buffer[startIndex + 1] == 'T' && state.buffer[startIndex + 2] == 'C'))
                                    {
                                        startIndex++;
                                    }
                                    packLength = 0;
                                }
                        //clear sign
                        rawp.endPack0 = 0;
                        rawps.endPack0 = 0;
                        rawpss.endPack0 = 0;
                        startIndex += packLength;
                    }
                    Marshal.FreeHGlobal(unmanagedPointer);
                    if (checkSource(handler, out IPinfo))
                    {
                        debug(2, "transaction.txt", string.Format("Readcallback IP({0})-Packet process finished BYTE({1}) PACKET({2})", IPinfo, bytesRead.ToString(), countPack.ToString()));
                    }
                }
                catch (Exception ex)
                {
                    debug(1, "transaction.txt", string.Format("Readcallback -Process packet error MES({0}) SOURCE({1})", ex.Message, ex.Source));
                }
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                if (checkSource(handler, out IPinfo))
                {

                    debug(3, "transaction.txt", string.Format("Readcallback IP({0})-BeginReceiveFinish", IPinfo));
                }
                //}
            }
        }
    }
}
